import re 


# openfile = Citrix configuration file path as the source
#transFile =  LTM configuration  file path as the destination
openFile = open( '/Users/k.ji/vscode/PycharmProjects/Citrix/ns1.conf' )
transFile = open('/Users/k.ji/vscode/PycharmProjects/Citrix/ns1.conf-after','a')

initConfig = openFile.read()
readConfig = initConfig.split('\n')
configLenth = len(readConfig)



# Returns True if given string is avalid IP Address, else returns False

def valid_IP_Address(sample_str):
    result = True
    match_obj = re.search( r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$", sample_str)
    if  match_obj is None:
        result = False
    else:
        for value in match_obj.groups():
            if int(value) > 255:
                result = False
                break
    return result




nodeList = []
memberList = []


# get all nodes info in nodeList
#nodeList structure： [[nodename , nodeip]]
for i in range(configLenth):
	if 'add server ' in readConfig[i]:
		nodeName = readConfig[i].split(" ")[2]
		nodeIP= readConfig[i].split(" ")[3]
		nodeList.append([nodeName,nodeIP])

#get all member info in memberList
#memberList structure ： [{membername:[ip,memberport]}]

for i in range(configLenth):
	if 'add service ' in readConfig[i]:
		memberName = readConfig[i].split(" ")[2]
		nodeName = readConfig[i].split(" ")[3]
		memberProtocal = readConfig[i].split(" ")[4]
		memberPort = readConfig[i].split(" ")[5]
		for nodeNameinList , nodeIPinList in nodeList:
			if nodeName == nodeNameinList:
				memberIP = nodeIPinList
				break
		memberList.append([memberName,memberIP,memberPort,memberProtocal])	




groupList = []
#group structure ： [groupName,memberIP,memberPort]
serviceGroupNameList = []
serviceGroupNameListDeduplicated = []
# serviceGroupName list is the pool config using bind serviceGroup..

for i in range(configLenth):
	if 'bind serviceGroup ' in readConfig[i]:
		groupName = readConfig[i].split(" ")[2]
		nodeName = readConfig[i].split(" ")[3]
		memberPort  = readConfig[i].split(" ")[4]
		for nodeNameinList , nodeIPinList in nodeList:
			if nodeName == nodeNameinList:
				memberIP = nodeIPinList
				break	
		serviceGroupNameList.append(groupName)
		groupList.append([groupName,memberIP,memberPort])

serviceGroupNameListDeduplicated = sorted(set(serviceGroupNameList),key=serviceGroupNameList.index)

serverGroupVS2GroupList = []   # when using serviceGroup config , record the vsname to group in the list for late use  [vsname,groupName]

for i in range(configLenth):
	if 'bind lb vserver' in readConfig[i] and readConfig[i].split(" ")[4] != '-policyName' and readConfig[i].split(" ")[4] not in serviceGroupNameListDeduplicated:
		groupName = readConfig[i].split(" ")[3]
		memberName = readConfig[i].split(" ")[4]
		for member in memberList:
			if member[0] == memberName:
				memberIP = member[1]
				memberPort = member[2]
				break
		groupList.append([groupName,memberIP,memberPort])
	if 'bind lb vserver' in readConfig[i] and readConfig[i].split(" ")[4] != '-policyName' and readConfig[i].split(" ")[4] in serviceGroupNameListDeduplicated:
		vsName = readConfig[i].split(" ")[3]
		groupName = readConfig[i].split(" ")[4]
		serverGroupVS2GroupList.append([vsName,groupName])



groupNameList = []
groupNameListDeduplicated = []
for groupName in groupList:
	groupNameList.append(groupName[0])
groupNameListDeduplicated = sorted(set(groupNameList),key=groupNameList.index)


#build pool configuration（fqdn support）
#group[1] = member ip address
#group[2] = member port

for groupName in groupNameListDeduplicated:
	first = 1
	for group in groupList:
		if  first == 1 and groupName == group[0] and valid_IP_Address(group[1]):
			groupConfig = 'tmsh create ltm pool Pool_' + groupName + ' members add { ' + group[1] + ":" + group[2] \
			+ ' { address ' + group[1] + ' } '
			transFile.write(groupConfig)
			first = 0
		elif first == 0 and groupName == group[0] and valid_IP_Address(group[1]):
			groupConfig = group[1] + ':' + group[2] + ' { address ' + group[1] + ' } '
			transFile.write(groupConfig)
		elif first == 1 and groupName == group[0] and not valid_IP_Address(group[1]):
			groupConfig = 'tmsh create ltm pool Pool_' + groupName + ' members add { ' + group[1] + ":" + group[2] + " " + "{ fqdn { autopopulate enabled name " \
						+ group[1] + " } } "
			transFile.write(groupConfig)
		elif first == 0 and groupName == group[0] and not valid_IP_Address(group[1]):
			groupConfig = group[1] + ':' + group[2] +  " " + "{ fqdn { autopopulate enabled name " + group[1] + " } } "
			transFile.write(groupConfig)
	groupConfig = '} monitor tcp load-balancing-mode round-robin \n'
	transFile.write(groupConfig)




#get vs info in vsList
# vsList structure : [vsName , protocol, vip, vport] , vsName = vserver(citrix) name = groupName

vsList = []

for i in range(configLenth):
	if 'add lb vserver' in readConfig[i]:
		vsName = readConfig[i].split(" ")[3]
		protocol = readConfig[i].split(" ")[4]
		vip = readConfig[i].split(" ")[5]
		vPort = readConfig[i].split(" ")[6]
		vsList.append([vsName,protocol,vip,vPort])


for vs in vsList:
	for vsName , groupName in serverGroupVS2GroupList:
		if vsName == vs[0]:
			protocol = vs[1]
			poolName = groupName
			vip = vs[2]
			vPort = vs[3]
			if protocol == 'HTTP' or protocol == 'SSL':
				vsConfig = 'tmsh create ltm virtual %s destination %s:%s pool Pool_%s profiles add { HTTP } source-address-translation { type automap } persist replace-all-with { source_addr }' %(vsName,vip,vPort,poolName)
			elif protocol == 'TCP':
				vsConfig = 'tmsh create ltm virtual %s destination %s:%s pool Pool_%s ip-protocol tcp source-address-translation { type automap } persist replace-all-with { source_addr }' %(vsName,vip,vPort,poolName)
			transFile.write(vsConfig  + '\n')
			break
	else:
		vsName = vs[0]
		poolName = vs[0]
		vsName = vs[0]
		protocol = vs[1]
		vip = vs[2]
		vPort = vs[3]
		if protocol == 'HTTP' or protocol == 'SSL':
			vsConfig = 'tmsh create ltm virtual %s destination %s:%s pool Pool_%s profiles add { HTTP } source-address-translation { type automap } persist replace-all-with { source_addr }' %(vsName,vip,vPort,poolName)
		elif protocol == 'TCP':
			vsConfig = 'tmsh create ltm virtual %s destination %s:%s pool Pool_%s ip-protocol tcp source-address-translation { type automap } persist replace-all-with { source_addr }' %(vsName,vip,vPort,poolName)
		transFile.write(vsConfig  + '\n')
